//
// Created by miaomiaole on 2024/1/20.
//
#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;


void on_mouse(int event, int x, int y, int flags, void *);

void show_imgs();


Mat src, erosion_dst, dilation_dst;
int erosion_elem = 0;
int erosion_size = 0;
int dilation_elem = 0;
int dilation_size = 0;
int const max_elem = 2;
int const max_kernel_size = 21;

void Erosion(int, void *);

void Dilation(int, void *);

void show_trackbarImgs() {

    src = imread("../picture_1663037518439.jpeg", IMREAD_COLOR);

    namedWindow("Erosion Demo", WINDOW_AUTOSIZE);
    namedWindow("Dilation Demo", WINDOW_AUTOSIZE);
    moveWindow("Dilation Demo", src.cols, 0);
    createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",
                   &erosion_elem, max_elem,
                   Erosion);
    createTrackbar("Kernel size:\n 2n +1", "Erosion Demo",
                   &erosion_size, max_kernel_size,
                   Erosion);
    createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo",
                   &dilation_elem, max_elem,
                   Dilation);
    createTrackbar("Kernel size:\n 2n +1", "Dilation Demo",
                   &dilation_size, max_kernel_size,
                   Dilation);
    Erosion(0, 0);
    Dilation(0, 0);
    waitKey(0);

}

int main() {
    // show_imgs();
    show_trackbarImgs();
}

Mat g_srcImage;
Point previousPoint;

void show_imgs() {
    g_srcImage = imread("../picture_1663037518439.jpeg", 1);
    imshow("cat", g_srcImage);
    setMouseCallback("cat", on_mouse, 0);
    waitKey(0);
}

/**
 * 设置事件
 * @param event
 * @param x
 * @param y
 * @param flags
 */
void on_mouse(int event, int x, int y, int flags, void *) {
    if (event == EVENT_LBUTTONDOWN) {
        // 获取鼠标坐标
        previousPoint = Point(x, y);
    } else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)) {
        Point pt(x, y);
        Point pt2(x * 2, y * 2);

        // 鼠标事件
        arrowedLine(g_srcImage, previousPoint, pt2, Scalar(255, 255, 255), 2, 5, 0);

        previousPoint = pt;

        imshow("cat", g_srcImage);
    }

}

void Erosion(int, void *) {
    int erosion_type = 0;
    if (erosion_elem == 0) { erosion_type = MORPH_RECT; }
    else if (erosion_elem == 1) { erosion_type = MORPH_CROSS; }
    else if (erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }
    // 像素结构，鼠标事件
    Mat element = getStructuringElement(erosion_type,
                                        Size(2 * erosion_size + 1, 2 * erosion_size + 1),
                                        Point(erosion_size, erosion_size));
    erode(src, erosion_dst, element);
    imshow("Erosion Demo", erosion_dst);
}

void Dilation(int, void *) {
    // 像素结构，鼠标事件
    int dilation_type = 0;
    if (dilation_elem == 0) { dilation_type = MORPH_RECT; }
    else if (dilation_elem == 1) { dilation_type = MORPH_CROSS; }
    else if (dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }
    Mat element = getStructuringElement(dilation_type,
                                        Size(2 * dilation_size + 1, 2 * dilation_size + 1),
                                        Point(dilation_size, dilation_size));
    dilate(src, dilation_dst, element);
    imshow("Dilation Demo", dilation_dst);
}